package com.hsytech.baoinbao.volleytool;

import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.hsytech.baoinbao.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by hsy on 2016/2/2.
 */
public class HttpUtil {
    private static final int TYPE_VOLLEY_ERROR = 0;

    private static final String MSG = "msg";
    private static final String CODE = "error";
    private static final String RESULT = "result";

    private static final int SUCCESS_CODE = 0;
    private static final int ERROR_CODE = 1;

    private static RequestQueue requestQueue = null;
    private static ProgressDialog dialog;

    public interface HttpCallback {
        void onSuccess(int what, JSONObject response);

        void onError(int what, int type, VolleyError error);

        void onErrorMsg(int what, String msg);
    }

    public static void init(Context applicationContext) {
        HttpUtil.requestQueue = Volley.newRequestQueue(applicationContext);
    }

    private static class MyDialog {

        public static void show(Context context) {
            if (dialog == null) {
                dialog = new ProgressDialog(context);
            }

            dialog.setTitle(null);
            dialog.setMessage("请稍候...");
            dialog.setCanceledOnTouchOutside(false);
            dialog.setCancelable(false);
            dialog.show();
        }

        public static void dismiss() {
            if (dialog != null && dialog.isShowing()) {
                dialog.dismiss();
                dialog = null;
            }

        }
    }

    private static void newRequest(final int what, final String url, final HttpCallback httpCallback, final int method, final Map<String, String> headers, final Map<String, String> params, final Context context) {
        if (null == HttpUtil.requestQueue) {
            return;
        }
        if (context != null) {
            MyDialog.show(context);
        }
        StringRequest stringRequest = new StringRequest(method, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (null != httpCallback) {
                    Log.d("mylog", "response" + response);
                    JSONObject jsonObject = null;
                    int code = -1;
                    try {
                        jsonObject = new JSONObject(response);
                        code = jsonObject.getInt(CODE);
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.d("mylog", " e.printStackTrace()" + e.getMessage());
                    }
                    if (code == SUCCESS_CODE) {
                        httpCallback.onSuccess(what, jsonObject);
                    } else if (code == ERROR_CODE) {
                        Log.d("mylog", "HTTP UTILS code==" + "1");
                        Log.d("mylog", "HTTP UTILS error MSG==" + jsonObject.optString(MSG));
                        httpCallback.onErrorMsg(what, jsonObject.optString(MSG));
                    } else if (code == -1) {
                        Log.d("mylog", "HTTP UTILS code==" + "-1");
                        Toast.makeText(context, R.string.msg_http_failure, Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Log.d("mylog", "HTTP UTILS httpCallback==" + "null");
                    Toast.makeText(context, R.string.msg_http_failure, Toast.LENGTH_SHORT).show();
                }
                MyDialog.dismiss();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                if (null != httpCallback) {
                    Log.d("mylog", "HTTP UTILS VolleyError toString==" + error.toString());
                    Log.d("mylog", "HTTP UTILS VolleyError getMessage==" + error.getMessage());
                    httpCallback.onError(what, TYPE_VOLLEY_ERROR, error);
                    MyDialog.dismiss();

                }
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                if (null != headers) {
                    Map<String, String> p = new HashMap<>();
                    if (null != super.getHeaders() && 0 != super.getHeaders().size()) {
                        p.putAll(super.getHeaders());
                    }
                    p.putAll(headers);
                    return p;
                } else {
                    return super.getHeaders();
                }
            }

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                if (null != params) {
                    Map<String, String> p = new HashMap<>();
                    if (null != super.getParams() && 0 != super.getParams().size()) {
                        p.putAll(super.getParams());
                    }
                    p.putAll(params);
                    return p;
                } else {
                    return super.getParams();
                }
            }
        };
        RetryPolicy policy = new DefaultRetryPolicy(30 * 1000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        stringRequest.setRetryPolicy(policy);
        HttpUtil.requestQueue.add(stringRequest);
        HttpUtil.requestQueue.start();
    }

    public static void httpGet(final int what, final String url, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.GET, null, null, context);
    }

    public static void httpPost(final int what, final String url, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.POST, null, null, context);
    }

    public static void httpPut(final int what, final String url, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.PUT, null, null, context);
    }

    public static void httpDelete(final int what, final String url, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, null, null, context);
    }

    public static void httpGetWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.GET, headers, null, context);
    }

    public static void httpPostWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.POST, headers, null, context);
    }

    public static void httpPutWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.PUT, headers, null, context);
    }

    public static void httpDeleteWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, headers, null, context);
    }

    public static void httpGetWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.GET, null, params, context);
    }

    public static void httpPostWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.POST, null, params, context);
    }

    public static void httpPutWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.PUT, null, params, context);
    }

    public static void httpDeleteWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, null, params, context);
    }

    public static void httpGetWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.GET, headers, params, context);
    }

    public static void httpPostWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.POST, headers, params, context);
    }

    public static void httpPutWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.PUT, headers, params, context);
    }

    public static void httpDeleteWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback, Context context) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, headers, params, context);
    }
}
